/*
 * DownLoadLyric.c
 *
 *  Created on: 2009-11-26
 *      Author: allan
 */
#include "include/ShowLyric.h"
#include "include/ShowLyricApp.h"
#include "include/ShowLyricDlg.h"
#include "include/SelLyricDlg.h"
#include "include/DownLoadLyric.h"
#include <glib.h>
#include <glib/gstdio.h>

struct {
	int pipe_search;
	int pipe_download;
}g_data = {0};

void DownLoadLyric(const gchar* lpszId, SongInfo info, gint nAppIndex)
{
	char szApp[512] = {0};
	AppInfo app = {0};
	theApp.m_player.GetSearchApp(nAppIndex, &app);
	sprintf(szApp, "/usr/share/ShowLyric/%s", app.szApp);
	pid_t child = fork();
	if (child == -1)
	{
		LyricLog("Fork Error!%s:%d\n",__FILE__ , __LINE__);
		return;
	}
	else if (child == 0)
	{
		char szArgv[4][512];
		sprintf(szArgv[0], "-i:\"%s\"", lpszId);
		sprintf(szArgv[1], "-t:\"%s\"", info.szTitle);
		sprintf(szArgv[2], "-a:\"%s\"", info.szArtist);
		sprintf(szArgv[3], "-o:\"%s\"", info.szLyricFileName);
		execl(szApp, szApp, szArgv[0],
		szArgv[1], szArgv[2], szArgv[3], (char * )0);
		exit(0);
	}

	DownLoadInfo * pinfo = (DownLoadInfo *)malloc(sizeof(DownLoadInfo));
	memcpy(&pinfo->info, &info, sizeof(info));
	pinfo->nAppIndex = nAppIndex;
	pinfo->nCount = 30;
	pinfo->child = child;
	if (g_timeout_add_seconds(1, (GSourceFunc)_DownLoadLyricProc, pinfo) == 0)
	{
		LyricLog("创建搜索时间事件失败!\n");
		free(pinfo);
		pinfo = NULL;
		return;
	}
}

gboolean _DownLoadLyricProc(DownLoadInfo * pInfo)
{
	AppInfo app = {0};
	theApp.m_player.GetSearchApp(pInfo->nAppIndex, &app);
	OnShowState("正在使用%s搜索歌词(%d)...", app.szName, pInfo->nCount);
	pInfo->nCount++;
	int iState;
	pid_t pr = waitpid(pInfo->child, &iState, WNOHANG);
	if (pr <= 0)
	{
		if (pInfo->nCount == 0)
		{
			kill(pInfo->child, SIGKILL);
			OnShowState("使用%s下载歌词超时！", app.szName);
			free(pInfo);
			return FALSE;
		}
		return TRUE;
	}

	LyricDebug("正在下载完毕......\n");

	if (theApp.m_player.IsCurrSong(pInfo->info))
	{
		theApp.m_LyricWnd.ParseLyric(pInfo->info.szLyricFileName);
	}

	free(pInfo);
	return FALSE;
}

gboolean _SearchLyric(SongInfo info, gboolean bSmartDownLoad, gint nAppIndex, gboolean bAutoTryElse, gboolean bFirst)
{
	gchar szTmpFileName[MAX_PATH] = { 0 };
	sprintf(szTmpFileName, "%s/tmp.txt", theApp.m_szConfigPath);
	if (g_remove(szTmpFileName) < 0)
	{
		// 删除文件出错
	}
	pid_t child = fork();
	char szApp[512] = {0};
	AppInfo app = {0};
	theApp.m_player.GetSearchApp(nAppIndex, &app);
	sprintf(szApp, "/usr/share/ShowLyric/%s", app.szApp);
	if (child == -1)
	{
		LyricLog("Fork Error!\n");
		return FALSE;
	}
	else if (child == 0)
	{
		char szArgv[3][512] =
		{
		{ 0 } };
		sprintf(szArgv[0], "-a:\"%s\"", info.szArtist);
		sprintf(szArgv[1], "-t:\"%s\"", info.szTitle);
		sprintf(szArgv[2], "-o:\"%s\"", szTmpFileName);
		execl(szApp, app.szApp, szArgv[0], szArgv[1], szArgv[2],
				(char * )0);
		exit(0);
	}

	SearchInfo * pinfo = (SearchInfo *)malloc(sizeof(SearchInfo));
	pinfo->nAppIndex = nAppIndex;
	strcpy(pinfo->szTmpFileName, szTmpFileName);
	memcpy(&pinfo->info, &info, sizeof(info));
	pinfo->nCount = 30;
	pinfo->bSmartDownLoad = bSmartDownLoad;
	pinfo->child = child;
	pinfo->bAutoTryElse = bAutoTryElse;
	if (bFirst)
	{
		pinfo->nFirstAppIndex = nAppIndex;
	}
	if (g_timeout_add_seconds(1, (GSourceFunc)_SearchLyricProc, pinfo) == 0)
	{
		LyricLog("创建搜索时间事件失败!\n");
		free(pinfo);
		pinfo = NULL;
		return FALSE;
	}
	return TRUE;
}

// 搜索歌词
gboolean SearchLyric(SongInfo info, gboolean bSmartDownLoad, gint nAppIndex, gboolean bAutoTryElse)
{
	return _SearchLyric(info, bSmartDownLoad, nAppIndex, bAutoTryElse, TRUE);
}

void SearchFailed(SearchInfo  Info)
{
	AppInfo app = {0};
	theApp.m_player.GetSearchApp(Info.nAppIndex, &app);
	gint nNextAppIndex = Info.nAppIndex + 1;
	if (theApp.m_player.GetSearchAppCount() == nNextAppIndex)
	{
		nNextAppIndex = 0;
	}

	if (Info.bAutoTryElse && nNextAppIndex != Info.nFirstAppIndex)
	{
		_SearchLyric(Info.info, Info.bSmartDownLoad, nNextAppIndex, Info.bAutoTryElse, FALSE);
	}
	else
	{
		OnShowState("无法搜索到歌词！歌曲信息:\n作者：%s\n歌名：%s", Info.info.szArtist, Info.info.szTitle);
	}
}

gboolean _SearchLyricProc(SearchInfo * pInfo)
{
	AppInfo app = {0};
	theApp.m_player.GetSearchApp(pInfo->nAppIndex, &app);
	OnShowState("正在使用%s搜索歌词(%d)...", app.szName, pInfo->nCount);
	pInfo->nCount--;
	int iState;
	pid_t pr = waitpid(pInfo->child, &iState, WNOHANG);
	if (pr <= 0)
	{
		if (pInfo->nCount == 0)
		{
			OnShowState("使用%s搜索歌词超时!", app.szName);

			if (theApp.m_player.IsCurrSong(pInfo->info))
			{
				SmartShowWnd(FALSE);
			}
			SearchFailed(*pInfo);
			free(pInfo);
			return FALSE;
		}
		return TRUE;
	}
	FILE * pFile = fopen(pInfo->szTmpFileName, "r");
	if (!pFile)
	{
		LyricLog("打开临时文件(%s)失败!iState=%ld", pInfo->szTmpFileName, iState);
		if (theApp.m_player.IsCurrSong(pInfo->info))
		{
			SmartShowWnd(FALSE);
		}
		SearchFailed(*pInfo);
		free(pInfo);
		return FALSE;
	}
	fseek(pFile, 0, SEEK_END);
	int nLen = ftell(pFile);
	gchar* lpszBuf = (gchar*)malloc(nLen);
	fseek(pFile, 0, SEEK_SET);
	// 解析列表并显示选择窗口
	GList* ListLyrics = NULL;
	LyricsListItem item = {0};
	while (fgets(lpszBuf, nLen, pFile))
	{
		if (memcmp(lpszBuf, "artist=", strlen("artist=")) == 0)
		{
			strncpy(item.szArtist, lpszBuf + strlen("artist="), MAX_PATH);
		}
		else if (memcmp(lpszBuf, "title=", strlen("title=")) == 0)
		{
			strncpy(item.szTitle, lpszBuf + strlen("title="), MAX_PATH);
		}
		else if (memcmp(lpszBuf, "id=", strlen("id=")) == 0)
		{
			strncpy(item.szID, lpszBuf + strlen("id="), MAX_PATH);
			LyricsListItem * pNewItem = (LyricsListItem *)malloc(sizeof(LyricsListItem));
			*pNewItem = item;
			ListLyrics = g_list_append(ListLyrics, pNewItem);

			memset(item.szArtist, 0, sizeof(item.szArtist));
			memset(item.szID, 0, sizeof(item.szID));
			memset(item.szTitle, 0, sizeof(item.szTitle));
			item.index++;
		}
	}
	fclose(pFile);
	pFile = NULL;
	free(lpszBuf);
	lpszBuf = NULL;
	int nLyricCount = g_list_length(ListLyrics);
	if (nLyricCount <= 0)
	{
		LyricLog("没有搜索到歌词！歌曲信息(%s, %s)", pInfo->info.szArtist, pInfo->info.szTitle);

		OnShowState("没有搜索到歌词！");
		SearchFailed(*pInfo);
	}
	else// if (nLyricCount > 0)
	{
		if (pInfo->bSmartDownLoad)
		{
			GList* first = g_list_first(ListLyrics);
			LyricsListItem *pItem = first->data;
			SongInfo info = pInfo->info;
			strncpy(info.szArtist, pItem->szArtist, MAX_PATH);
			strncpy(info.szTitle, pItem->szTitle, MAX_PATH);
			DownLoadLyric(pItem->szID, info, pInfo->nAppIndex);
			_FreeList(ListLyrics);
		}
		else
		{
			GladeXML* xml = glade_xml_new(SEL_LYRIC_GLADE_FILE, NULL, NULL);
			gtk_widget_show(SelLyricDlgInit(xml, ListLyrics, pInfo->info, pInfo->nAppIndex));
		}
	}


	free(pInfo);
	return FALSE;
}
